/*
 * 这是最简单的javascript股票账户模拟类
 *
 * 由账户基本信息={name, money ,feeRate, taxRate}初始化账户,
 * 账户操作历史=[{type, target, number ,price, date}...]指定过程
 * 上述两个参数进行构造.
 * 运行runAccount()方法模拟投资历史,计算出账户的最后情况
 * toString()方法把账户的主要信息转换成字符串,方便显示
 * 最后更新日期: 2019-05-24 8:45
 */

/* 账户类定义 */
class Account {
  
  constructor(accountData, histroy) {
    this._name = ('name' in accountData)?accountData['name']:'defaultUser';
    this._money = ('money' in accountData)?accountData['money']:100*10000; //持有现金   
    this._feeRate = ('feeRate' in accountData)?accountData['feeRate']:2.5/10000;
    this._taxRate = ('taxRate' in accountData)?accountData['taxRate']:1.0/1000;
    this._targets = {}; // 持有标的表
    this._histroy = histroy; // 操作历史
  }
  
  toString(){
    var strList = ['--- Money ---', this._money, '--- Targets ---'];
    var targets = this._targets;
    for (var target in targets) {
      let number = targets[target];
      strList.push(target+' : '+number);
    }
    return strList.join('\n');
  }
  
  runAccount(){
    for (var i = 0;i < this._histroy.length;i++){
      // 对单条历史进行处理准备
      var {type, target, number, price, date} = this._histroy[i];  
      type = type.toLowerCase();
      if (!(target in this._targets))  this._targets[target] = 0;
      // 准备完毕,开始计算
      var deal = number*price; // 成交额
      var fee = deal*this._feeRate; // 佣金
      if (fee < 5) fee = 5; // 佣金最低5元
      if (type == 'buy'){
        this._money -= (deal+fee); 
        this._targets[target] += number;
      }else{
        // 计算印花税,'1'或'5'开始的是基金,免税
        if (!(target[0] == '5' || target[0] == '1')) fee += deal*this._taxRate;
        this._money += (deal-fee);
        this._targets[target] -= number;
      }
    }
  }
  
}
 
/* 使用与测试 */

// 账户信息
var accountData = {
  'name': 'testUser',
  'money': 100.0*10000, // 初始现金
  'feeRate': 2.1/10000, // 佣金率
  'taxRate': 1.0/1000  // 印花税税率
};

// 投资操作历史表
var histroy = [
  {'type': 'buy', 'target': '600000', 'number': 10000, 'price': 10.00, 'date': '2019-05-23'},
  {'type': 'sell', 'target': '600000', 'number': 10000, 'price': 10.00, 'date': '2019-05-24'},
  {'type': 'buy', 'target': '600001', 'number': 11100, 'price': 12.00, 'date': '2019-05-23'},
  {'type': 'buy', 'target': '600002', 'number': 20000, 'price': 14.00, 'date': '2019-05-24'}
];

// 新建账户并模拟操作,显示信息
var myAccount = new Account(accountData, histroy);
myAccount.runAccount();
var msg = myAccount.toString();
if(console) console.log(msg);
msg;

